---
sidebar_position: 2
---

# Исходная точка

## Структура проекта

Давайте рассмотрим проект, в котором рекомендуется вести разработку лабораторных работ. Получить данный проект можно из [репозитория](https://hub.mos.ru/iu5bmstu/lections-and-labs/cpp2/templates).

Папка проекта выглядит следующим образом:

```bash
labs
├── lab1
│   ├── CMakeList.txt
│   ├── README.md
│   └── main.cpp
├── lab2
...
└── lab9
```

:::info Занимательный факт

Структура репозитория представлена с помощью [Box-drawing character](https://en.wikipedia.org/wiki/Box-drawing_character).
:::

Последовательно разберемся с тем, что содержится в папке:

- `CMakeList.txt` - это мы будем трогать и изучать подробнее далее.
- `README.md` - описание решения в формате Markdown. Если вы не знаете о Markdown, то рекомендуется это [исправить](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax).
- `main.cpp` - точка входа в нашу программу.

Давайте теперь разбираться с тем, что содержит сейчас `CMakeList.txt`.

## Описание `CMakeList.txt`

:::info
При подготовке материала использовалась статья [Полное руководство по CMake. Часть вторая: Система сборки](https://itnan.ru/post.php?c=1&p=432096).
:::

Про то, что такое CMake вы узнаете из [лекции](../../../lectures/cmake/intro.md). Здесь же не вдаваясь в подробности рассмотрим как с ним работать. В  `CMakeList.txt` содержится следующее:

```cmake
cmake_minimum_required(VERSION 3.23)
project(lab1)

set(CMAKE_CXX_STANDARD 17)

add_executable(lab1 main.cpp)

IF (NOT WIN32)
target_link_libraries(lab1 m)
ENDIF()
```

### `cmake_minimum_required`

Команда [cmake_minimum_required](https://cmake.org/cmake/help/latest/command/cmake_minimum_required.html) проверяет запущенную версию CMake: если она меньше указанного минимума, то CMake завершает свою работу фатальной ошибкой.

:::caution

Это вы оставляете без изменений и не удаляете. В противном случае вы не будете проходить тестирование кода при запросах на слияние.

:::

### `project`

В начале любого CMakeLists.txt следует задать характеристики проекта командой [project](https://cmake.org/cmake/help/latest/command/project.html) для лучшего оформления интегрированными средами и прочими инструментами разработки.

Вызывать эту функцию рекомендуется по умолчанию, так как она позволит инициализировать сборщик и переменные окружения.

:::caution

Название проекта у вас должно обязательно совпадать с названием директории для лабораторной работы. В противном случае у вас будет ломаться конвейер проверки кода на запросе при слиянии.

:::

### `set(CMAKE_CXX_STANDARD 17)`

Этой функцией вы устанавливаете требование определенного языкового стандарта - C++ 17.

Это требование можно установить [различным образом](https://cmake.org/cmake/help/latest/manual/cmake-compile-features.7.html#optional-compile-features). Но здесь это сделано именно так.

:::caution

Это вы оставляете без изменений и не удаляете.

:::

### `add_executable`

Команда [add_executable](https://cmake.org/cmake/help/latest/command/add_executable.html) компилирует исполняемый файл с заданным именем из списка исходников. Важно отметить, что окончательное имя файла зависит от целевой платформы (например, `<ExecutableName>.exe` или просто `<ExecutableName>`).

:::caution

Это вы меняете осторожно.

:::

### `IF-ENDIF`

CMake - очень мощная штука (а под капотом вообще магическая штука). CMake - не компилирует программы! CMake подготавливает среду, чтобы уже другие средства, например, [MSBuild](https://learn.microsoft.com/ru-ru/visualstudio/msbuild/msbuild), [Ninja](https://ninja-build.org/) и [Make](https://www.gnu.org/software/make/), уже собрали приложения. Иными словами, [CMake не занимается непосредственно сборкой](https://habr.com/ru/post/155467/), а лишь генерирует файлы сборки из предварительно написанного файла сценария `CMakeLists.txt` и предоставляет простой единый интерфейс управления.

CMake имеет кучу встроенных средств, позволяющих определить то, на какой платформе он работает, и найти запрашиваемые библиотеки для [линковки](https://habr.com/ru/company/otus/blog/432834/) ([компановка объектных файлов и библиотек](https://radioprog.ru/post/1042)).

И если мы начинаем говорить про кроссплатформенность, то без конструкций условия никуда не деться.

На платформе `WIN32` требуется явно требуется скомпоновать математическую библиотеку `math.h` и проект, в котором мы хотим использовать ее. Делается это с помощью команды [target_link_libraries](https://cmake.org/cmake/help/latest/command/target_link_libraries.html) компонует библиотеку или исполняемый файл с другими предоставляемыми библиотеками. Первым аргументом данная команда принимает название цели, сгенерированной с помощью команд [add_executable](https://cmake.org/cmake/help/latest/command/add_executable.html) или [add_library](https://cmake.org/cmake/help/latest/command/add_library.html), а последующие аргументы представляют собой названия целей библиотек или полные пути к библиотекам.

:::caution

Этот блок вы изменяете по необходимости.

:::

## Резюме

Мы рассмотрели всю магию CMake для сборки простых консольных приложений? Было страшно?

На самом деле всю "страшную" работу CMake прячет от глаз разработчиков:

![Мем про CMake](images/cmake-mem.jpeg)

Ради интереса можете поизучать [исходники](https://gitlab.kitware.com/cmake/cmake).

Далее создадим статическую библиотеку в рассматриваемой директории и подключим ее к нашему проекту `lab1`.
